/*
抽象工厂模式（Abstract Factory Pattern）是一种创建型设计模式，它提供了一种创建一系列相关或相互依赖对象的接口，而无需指定具体实现类。
抽象工厂模式将对象的创建与使用解耦，使得客户端代码与具体类的实现细节分离，提供了更好的灵活性和可扩展性。

抽象工厂模式的核心思想是定义一个抽象工厂接口，该接口声明了一系列用于创建不同类型对象的方法。
每个具体工厂都实现了抽象工厂接口，并负责创建一系列相关的对象。
客户端代码通过抽象工厂接口来创建对象，而不需要关心具体的实现类。

以下是一个使用抽象工厂模式实现的C语言例程：
*/

#include <stdio.h>
#include <stdlib.h>

// 抽象产品A接口
typedef struct
{
    void (*printInfo)();
} AbstractProductA;

// 具体产品A1
typedef struct
{
    AbstractProductA product;
    int value;
} ConcreteProductA1;

// 具体产品A1的打印方法
void printInfoA1(const ConcreteProductA1 *product)
{
    printf("Concrete Product A1: %d\n", product->value);
}

// 具体产品A2
typedef struct
{
    AbstractProductA product;
    char *name;
} ConcreteProductA2;

// 具体产品A2的打印方法
void printInfoA2(const ConcreteProductA2 *product)
{
    printf("Concrete Product A2: %s\n", product->name);
}

// 抽象产品B接口
typedef struct
{
    void (*printInfo)();
} AbstractProductB;

// 具体产品B1
typedef struct
{
    AbstractProductB product;
    float price;
} ConcreteProductB1;

// 具体产品B1的打印方法
void printInfoB1(const ConcreteProductB1 *product)
{
    printf("Concrete Product B1: %.2f\n", product->price);
}

// 具体产品B2
typedef struct
{
    AbstractProductB product;
    int quantity;
} ConcreteProductB2;

// 具体产品B2的打印方法
void printInfoB2(const ConcreteProductB2 *product)
{
    printf("Concrete Product B2: %d\n", product->quantity);
}

// 抽象工厂接口
typedef struct
{
    AbstractProductA *(*createProductA)();
    AbstractProductB *(*createProductB)();
} AbstractFactory;

// 具体工厂1
typedef struct
{
    AbstractFactory factory;
} ConcreteFactory1;

// 具体工厂1的创建产品A方法
AbstractProductA *createProductA1()
{
    ConcreteProductA1 *product = (ConcreteProductA1 *)malloc(sizeof(ConcreteProductA1));
    product->product.printInfo = printInfoA1;
    product->value = 10;
    return (AbstractProductA *)product;
}

// 具体工厂1的创建产品B方法
AbstractProductB *createProductB1()
{
    ConcreteProductB1 *product = (ConcreteProductB1 *)malloc(sizeof(ConcreteProductB1));
    product->product.printInfo = printInfoB1;
    product->price = 19.99;
    return (AbstractProductB *)product;
}

// 具体工厂2
typedef struct
{
    AbstractFactory factory;
} ConcreteFactory2;

// 具体工厂2的创建产品A方法
AbstractProductA *createProductA2()
{
    ConcreteProductA2 *product = (ConcreteProductA2 *)malloc(sizeof(ConcreteProductA2));
    product->product.printInfo = printInfoA2;
    product->name = "Product A2";
    return (AbstractProductA *)product;
}

// 具体工厂2的创建产品B方法
AbstractProductB *createProductB2()
{
    ConcreteProductB2 *product = (ConcreteProductB2 *)malloc(sizeof(ConcreteProductB2));
    product->product.printInfo = printInfoB2;
    product->quantity = 100;
    return (AbstractProductB *)product;
}

int main()
{
    // 使用具体工厂1创建产品A和产品B
    AbstractFactory *factory1 = (AbstractFactory *)malloc(sizeof(ConcreteFactory1));
    factory1->createProductA = createProductA1;
    factory1->createProductB = createProductB1;
    AbstractProductA *productA1 = factory1->createProductA();
    AbstractProductB *productB1 = factory1->createProductB();
    productA1->printInfo(productA1); // 输出结果为 "Concrete Product A1: 10"
    productB1->printInfo(productB1); // 输出结果为 "Concrete Product B1: 19.99"

    // 使用具体工厂2创建产品A和产品B
    AbstractFactory *factory2 = (AbstractFactory *)malloc(sizeof(ConcreteFactory2));
    factory2->createProductA = createProductA2;
    factory2->createProductB = createProductB2;
    AbstractProductA *productA2 = factory2->createProductA();
    AbstractProductB *productB2 = factory2->createProductB();
    productA2->printInfo(productA2); // 输出结果为 "Concrete Product A2: Product A2"
    productB2->printInfo(productB2); // 输出结果为 "Concrete Product B2: 100"

    return 0;
}

/*
在上面的例程中，定义了抽象产品A和抽象产品B接口，以及它们的具体实现类。
接着定义了抽象工厂接口，该接口声明了创建产品A和产品B的方法。
然后，实现了两个具体工厂类，分别负责创建一系列相关的产品。

在main函数中，首先使用具体工厂1创建产品A1和产品B1，并调用它们的printInfo方法来输出信息。
接着使用具体工厂2创建产品A2和产品B2，并调用它们的printInfo方法来输出信息。
由于客户端代码只与抽象工厂接口和抽象产品接口交互，而不涉及具
*/